'''系统模块'''
import random
import sys

#sys记录程序所在环境系统的一些信息
# import sys
# print(sys.version)#查看版本以字符串的形式
# print(type(sys.version))#str
# print(sys.version_info)
# print(sys.version_info.major)#主版本号
# print(type(sys.version_info))#对象
#
# print(sys.argv)#运行时命令行参数列表
# print(type(sys.argv))#list
#
# sys.exit()#程序运行到此处，后续程序不会再执行



'''自定义模块：用户自己创建的模块，命名规则等同于变量的命名规则'''



'''模块化编程'''
#可实现协同开发
#程序更便于维护/升级
#提高了复用率
#解决了变量名的冲突问题



'''import语句在搜索模块的顺序'''
#  step1 当前路径寻找
#  step2 sys.path提供的路径中去寻找，用户也可以给这个path添加元素
#        sys.path.append("路径")
#  step3 查找内置模块

# print(sys.path)
# print(type(sys.path))#list
# sys.path.append("D:\\Users\\Python\\PycharmProjects\\PythonProject1\\pythonproject01")



'''模块的加载过程'''
# 如果一个模块被导入了，其中内部所有的内容都会执行一遍
# 如果一个模块已经被导入了，再次导入时不会重新执行其内容



'''导入模块的执行过程'''
# step1 去搜索路径下选择模块(.py)
# step2 判断一下是否有该模块对应的.pyc文件。如果有，而且pyc比py文件新
#         就执行加载pyc文件
#         如果没有pyc，或者pyc不比py文件新，就先生成pyc文件，再加载
# pyc文件是python的二进制文件，是py文件编译后的文件，是字节码文件，只用来解释执行的，而且跨平台



'''模块的常用属性'''
# __doc__：绑定的模块的文档字符串，任何模块都有这个属性
# __file__：绑定的模块路径名。1）内置模块报错，没有这个属性
#           2）自定义模块有这个路径，记录的模块路径名 3）第三方模块有这个属性，记录模块所在包的init文件
# __name__：绑定模块的名字，如果某一个模块作为程序入口，那这个模块的这个属性，绑定的"__main__"
# __all__：列表，用来存储一个模块可以被导出的属性，并不是所有的模块都有这个属性，
#          如果一个模块定义了这个属性，只有这个列表中定义了的变量才会被导出

# import math
# print(math.__doc__)#模块的文档字符串



'''模块的隐藏属性'''
# 在模块中，以_开头的属性，在使用from XX import * 时不会被导入



'''random'''
# random.random()#随机生成0~1的浮点数
# random.uniform(a,b)#随机生成a~b之间的浮点数，a和b的大小没有要求
# random.randint(a,b)#随机生成a~b之间的整数
# random.randrange([start,]stop[,step])#随机得到一个整数，start-stop之间
# random.choice(sequence)#从序列中随机得到一个元素
# random.shuffle(x)#将一个列表的元素随机打乱
# random.sample(sequence,n)#随机的从这个序列中截取部分内容，并打乱




#1，猜数字，程序随机生成一个0~100的随机整数，以循环的方式让用户来猜，
#共10次猜的机会工每一次给出猜大了，猜小了，猜对了的提示，猜对时停止循环

# i = 0
# n = random.randint(0, 100)
# for i in range(10):
#     m = int(input("请输入随机整数："))
#     if m == n:
#         print("猜对啦！！！")
#         break
#     elif m>n:
#         print("猜大了")
#     elif m<n:
#         print("猜小了")
#     i+=1
#     print("还剩",10-i,"次机会")


# 2、模拟斗地主的发牌逻辑
#一共54个牌，三个人，每人17张牌另外保留三张纸牌
# kind = ["\u2660", "\u2663", "\u2665","\u2666"]
# number = ["A","K","Q","J","2","3","4","5","6","7","8","9","10"]
# L = [x+y for x in kind for y in number]+["大王","小王"]
# random.shuffle(L)
# input("按回车给第一个人发牌:")
# one = L[0:17]
# print(one)
# input("按回车给第二个人发牌:")
# two = L[17:34]
# print(two)
# input("按回车给第三个人发牌:")
# three = L[34:51]
# print(three)
# input("按回车得到三张牌")
# dipai = L[51:]
# print(dipai)




'''包package'''
# 包是将模块以文件夹的形式进行分组管理的方法
# 作用：对一系列模块进行分组管理，避免命名冲突，加载时可以加载一部分或者所有模块
# __init__.py文件，在包加载时自定调用
# 包的导入和模块的导入一样



'''错误和异常'''
# 当异常发生时，程序不会再往下继续执行，而是转去调用的地方等待处理

# try except:
# try:
#     程序片段
# except:错误类型[as 别名]
#     处理语句
# except:错误类型[as 别名]
#     处理语句
# ... ...
# else:
#     未发生异常执行的语句
# finally:
#     最终执行的语句

# 作用：尝试捕获异常，当异常发生时，捕获到该异常，并且给了处理方式，防止程序终止
# as 对捕获到的异常起别名
# expect 一个或多个
# else 最多只能有一个，可以不写
# finally 最多只能有一个，可以不写


# try finally:
# try:
#     程序片段
# finally:
#     最终语句
# finally必须要有，不可以有except。不管是否发生异常，最终都要执行finally，不会改变程序的状态



'''异常的处理'''
#自定义一个函数，表示将n个苹果分给指定个数的人
# err1 = "类型不对"
# def div_apple(n):
#     num = int(input("请输入分的人数："))#可能会产生异常
#     cnt = n/num#可能会产生异常
#     print(n,"个苹果，分给",num,"个人，每人分得",cnt,"个")
#
# try:
#     div_apple(100)
# except ValueError as err2:
#     print(err1)
# except ZeroDivisionError as err3:
#     print("不能除以0")
# else:
#     print("没有发生异常")
# finally:
#     print("finally语句")


'''try finally'''
# def cook():
#     print("打开天然气")
#     try:
#         num = int(input("请输入煎鸡蛋的个数"))
#     finally:
#         print("关闭天然气")
#
# cook()



'''raise触发'''
# 语法 raise 异常类型    或者    raise 异常对象
# 作用： 认为触发一个异常，让程序进入异常状态

# def f():
#     print("f函数开始执行")
#     # raise ZeroDivisionError#触发一个错误类型
#     zero = ZeroDivisionError("不能除以0")#触发一个错误对象
#     print("f函数执行结束")
#
# f()



'''assert'''
# 语法：assert 真值表达式，错误数据（通常是字符串）
# 作用：当表达式为false的时候，用错误数据创建一个ssertionError（断言失败）
# 类型的对象：并且程序进入终止状态

# def f():
#     print("f函数开始执行")
#     a=1
#     b=2
#     assert a<b,"断言是不是失败了？？"#表达式可以理解为 业务的结果
#     print("f函数执行结束")
# try:
#     f()
# except Exception as e:
#     print(e)


'''总结'''
# try - except:捕获异常并做处理，让程序不会因为异常而进入终止状态
# try - finally:不管是否发生异常，都要做一些事情，不会改变程序的状态
# raise assert:用于消息的发生



'''模拟造房子过程'''
#打地基：如果打到了地下水，发现了文物，就使用raise或者assert，让程序进入终止状态

#盖房子：如果碰到高压线了，或者太高了（有机场），就使用raise或者assert，让程序进入终止状态


# def f1():
#     print("开始打地基")
#     # if random.random() < 0.4:#打到地下水
#     #     raise ValueError
#     # if random.random() > 0.7:#找到文物
#     #     raise ZeroDivisionError
#     assert random.random() < 0.4,"打到地下水"
#     assert random.random() > 0.7,"找到文物"
#     print("地基完成")
#
# try:
#     f1()
# except AssertionError as a :
#     print(a)

def f2():
    print("开始盖房子")
    # if random.random() < 0.3:
    #     raise ValueError
    # if random.random() > 0.9:
    #     raise ZeroDivisionError
    assert random.random() < 0.3,"碰到高压线"
    assert random.random() > 0.9,"太高了"
    print("房子完成")

try:
    f2()
except AssertionError as e:
    print(e)



